<?php
/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

class Server{
    private $url = null;
    private $name = null;
    private $commSocket = null;
    private $commPort = null;
    private $ftpSocket = null;
    private $ftpPort = null;

    public function Server($name, $url, $commPort, $ftpPort){
        $this->name = $name;
        $this->url = $url; //save the url
        $this->commPort = $commPort; //save the port
        $this->ftpPort = $ftpPort; //save the ftp port
    }
  
    private function commConnect(){
        $this->commSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //create a socket
        if(socket_connect($this->commSocket,$this->url,$this->commPort)){//connect to the server
            ob_implicit_flush(true); //set flushing of output to true
            return true; //return successful
        }else{
            return false; //return unsuccessful
        }
         
    }
    
    public function getName(){
        return $this->name;
    }
    
    public function getUrl(){
        return $this->url;
    }
    
    public function getCommPort(){
        return $this->commPort;
    }
    
    public function getFtpPort(){
        return $this->ftpPort;
    }
    
    private function ftpConnect(){
        $this->ftpSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //create an ftp socket
        if(socket_connect($this->ftpSocket,$this->url,$this->ftpPort)){//connect to the server
            ob_implicit_flush(true);
            return true;
        }else{
            return false;
        }
    }
    
    
    public function checkAvailability(){
        if($this->commConnect()){
            $request = "availability\r\n";
            $request .= "Host servermanager.sfsu.edu\r\n";
            socket_write($this->commSocket, $request, strlen($request));
            $response = socket_read($this->commSocket, 1024);
            $this->commDisconnect();
            if($response == "OK"){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    
    public function getStatus(){
        if($this->commConnect()){ //if the connection was successful
            $request = "system-status\r\nHost servermanager.sfsu.edu\r\n"; //build request
            socket_write($this->commSocket, $request, strlen($request)); //send the request
            $response = socket_read($this->commSocket, 1024); //read the response from the exec server
            $this->commDisconnect(); //close the socket
            return $response;
        }
    }
    public function isPublic(){
        if($this->commConnect()){ //if the connection was successful
            $request = "public?\r\nHost servermanager.sfsu.edu\r\n";
            socket_write($this->commSocket, $request, strlen($request)); //send the request
            $response = socket_read($this->commSocket, 1024); //read the response from the exec server
            $this->commDisconnect(); //close the socket
            if($response == "YES"){
                return true;
            }else{
                return false;
            }
        }
    }
    public function hasGPU(){
        if($this->commConnect()){
            $request = "gpu?\r\n";
            $request.= "Host servermanager.sfsu.edu\r\n";
            socket_write($this->commSocket, $request, strlen($request));
            $response = socket_read($this->commSocket, 1024);
            $this->commDisconnect(); //close the socket
            if($response == "YES"){
                return true;
            }else{
                return false;
            }
        }
    }
    public function getJobStatus($jobID){
        if($this->commConnect()){
            $request = "job-status id=1\r\n";
            $request .= "Path /jobs/".$jobID."/output/\r\n";
            $request .= "Host servermanager.sfsu.edu\r\n";
            socket_write($this->commSocket, $request, strlen($request));
            $response = socket_read($this->commSocket, 1024);
            $this->commDisconnect();
            return $response;
        }
    }
    public function executeJob($jobID){
        if($this->commConnect()){
            $request = "execute\r\n";
            $request .= "Path /jobs/".$jobID."/\r\n";
            $request .= "Host servermanager.sfsu.edu\r\n";
            socket_write($this->commSocket, $request, strlen($request));
            $response = socket_read($this->commSocket, 1024);
            $this->commDisconnect();
            if($response == "OK"){
                return true;
            }else{
                return false;
            }
        }
    }
    
    public function createJob($jobID, $xml, $inputFiles = null){
        if($this->commConnect()){ //if the connection was successful
            $request = "create-job id=".$jobID."\r\n";
            $request .= "Host servermanager.sfsu.edu\r\n\r\n";
            $request .= $xml."\n"; //attach job xml
            socket_write($this->commSocket,$request,strlen($request)); //send the request
            $response = socket_read($this->commSocket, 1024); //read response from exec server
            $this->commDisconnect(); //close the socket
            
            for($uploadCount=0, $success=false; $uploadCount<count($inputFiles); $uploadCount++){
                $success = $this->uploadFile($jobID,$inputFiles[$uploadCount]);
            }
            if($success == false){
                return $uploadCount;
            }else{
                return $this->executeJob($jobID);
            }
        }
    }
    
    public function downloadResultFiles($userID, $jobID){
        if($this->ftpConnect()){
            $response = "";
            $request = "download\r\n";
            $request .= "/jobs/".$jobID."/output/\r\n"; //build the request
            socket_write($this->ftpSocket,$request, strlen($request));
            $response = socket_read($this->ftpSocket,2048);
            $this->ftpDisconnect(); //close the ftp socket
            
            $lines = explode("\n",$response);
            for($i=0,$count=0;$i<=(sizeof($lines)/2);$i=$i+2,$count++){
                $nameheader = explode(" ",$lines[$i]);
                $sizeheader = explode(" ",$lines[$i+1]);
                $fname = $nameheader[1];
                $fsize = $sizeheader[1];
                
                $this->ftpConnect();
                $request = "download\r\n";
                $request .= "/jobs/".$jobID."/output/".$fname."\r\n";
                $request .= "File-Size ".(int)$fsize."\r\n";
                socket_write($this->ftpSocket,$request,strlen($request));
                
                $chunk = "";
                $file = "";
                do{
                    $chunk = socket_read($this->ftpSocket,1024);
                    if(!empty($chunk)){
                        echo ".";
                        $file .= $chunk;
                    }
                }while(!empty($chunk));
                $this->ftpDisconnect(); //close the ftp socket
                file_put_contents("C:/wicefs/users/".$userID."/".$fname, $file);
            }
            return $count;
        }
    }
    
    private function uploadFile($jobID, $filepath){
        if(file_exists($filepath)){ //if the file exists
            $file = file_get_contents($filepath, FILE_BINARY, null, 0, filesize($filepath)); //read its contents into $file
            
            $extpos = strrpos($filepath, "."); //This is where the position of the extension
            $namepos = strrpos($filepath, "/"); //This is the begining of the file name
            if(!$namepos){ //if there is no "/"
                // this is a local file and just the file name
                $filename = substr($filepath, 0, $extpos); //save file name until extension position
            }else{
                // this is not a local file. includes slashes
                $filename = substr($filepath, $namepos+1,$extpos); //save from last "/"
            }
            $ext = substr($filepath, $extpos+1,strlen($filepath)-1); //save the extension
            
            $request = "upload\r\n";
            $request .= "/jobs/".$jobID."/input/\r\n"; //build relative path for execution server
            $request .= "File-Size ".filesize($filepath)."\r\n"; //add file size header
            $request .= "File-Name ".$filename.".".$ext."\r\n"; //add file name header
            
            if($this->ftpConnect()){ //connect to exec ftp server 
                socket_write($this->ftpSocket,$request); //send the request
                $response = socket_read($this->ftpSocket, 1024); //read response from exec server
                if($response == "OK"){ //if the response was OK
                    socket_send($this->ftpSocket,$file,filesize($filepath),null); //send the file
                    $this->ftpDisconnect(); //close the socket
                    return true;
                }else{
                    $this->ftpDisconnect();
                    return false;
                }
            }else{
                echo "ftp could not connect";
                return false;
            }
        }
    }
    
    private function commDisconnect(){
        socket_close($this->commSocket);
    }    
    private function ftpDisconnect(){
        socket_close($this->ftpSocket);
    }
}
?>
 